package com.example.vue.sys.service.impl;

import com.example.vue.comm.domain.ResultData;
import com.example.vue.comm.util.IdUtil;
import com.example.vue.comm.util.WebUtil;
import com.example.vue.sys.domain.SysMenu;
import com.example.vue.sys.mapper.SysMenuMapper;
import com.example.vue.sys.service.SysMenuService;
import com.example.vue.sys.vo.MenuFormVo;
import com.example.vue.sys.vo.MenuTreeVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统菜单
 *
 * @author zhouxl
 * @DATE 2020/11/30
 * @descriptoin
 */
@Component
public class SysMenuServiceImpl implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public ResultData menuTree(Map<String, Object> params) {
        ResultData success = ResultData.success(null);
        List<Map<String, Object>> menuList = sysMenuMapper.queryMenuList(params);
        if (Objects.isNull(menuList)) {
            success.setCode(400);
            success.setMessage("当前并无任何菜单信息,请初始化菜单信息");
            return success;
        }
        List<Map<String, Object>> levelMenuList = new ArrayList<>();
        subMenuTreeList(menuList, levelMenuList, 1);
        success.setData(levelMenuList);
        return success;
    }

    /**
     * 查询树结构信息
     *
     * @param params
     */
    private MenuTreeVo menuTreeList(Map<String, Object> params) {

        return null;
    }

    /**
     * 查询当前菜单下所有的子节点信息
     *
     * @param menuList
     */
    private void subMenuTreeList(List<Map<String, Object>> menuList, List<Map<String, Object>> levelMenuLis, int grade) {
        if (Objects.isNull(menuList) || menuList.size() == 0) {
            return;
        }
        if (grade == 1) {
            Iterator<Map<String, Object>> it = menuList.iterator();
            while (it.hasNext()) {
                Map<String, Object> next = it.next();
                if ((int) next.get("grade") == grade) {
                    levelMenuLis.add(next);
                    it.remove();
                }
            }
            subMenuTreeList(menuList, levelMenuLis, grade + 1);
        } else {
            for (Map<String, Object> map : levelMenuLis) {
                String menuNo = (String) map.get("menuNo");
                Iterator<Map<String, Object>> it = menuList.iterator();
                List<Map<String, Object>> subMenuList = new ArrayList<>();
                while (it.hasNext()) {
                    Map<String, Object> next = it.next();
                    String nextPmenuNo = (String) next.get("pMenuNo");
                    if (menuNo.equals(nextPmenuNo)) {
                        subMenuList.add(next);
                        it.remove();
                    }
                }
                map.put("treeList", subMenuList);
                subMenuTreeList(menuList, subMenuList, grade + 1);
            }
        }
    }

    @Override
    public ResultData addMenu(MenuFormVo menuForm) {
        ResultData<SysMenu> sysMenu = createSysMenu(menuForm);
        int update = 0;
        try {
            update = sysMenuMapper.addMenu(sysMenu.getData());
        } catch (Exception ex) {
            sysMenu.setMessage("系统异常");
        }
        sysMenu.setMessage(update != 0 ? "添加成功" : "添加失败");
        return sysMenu;
    }

    @Override
    public ResultData menuList(MenuFormVo menuFormVo) {
        //        int grade = menuFormVo.getGrade()-1;
        int grade = menuFormVo.getGrade();
        menuFormVo.setGrade(grade == 0 ? menuFormVo.getGrade() : grade);
        List<Map<String, Object>> menuList = sysMenuMapper.menuList(menuFormVo);
        List<Map<String, Object>> levelMenuList = new ArrayList<>();
        subMenuTreeList(menuList, levelMenuList, 1);
        return ResultData.success(levelMenuList);
    }

    @Override
    public ResultData queryMenuById(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        Map<String, Object> menuInfo = sysMenuMapper.queryMenuById(params);
        if (Objects.isNull(menuInfo)) {
            data.setCode(400);
            data.setMessage("添加失败,添加的菜单的父级菜单不存在");
            return data;
        }
        List<Map<String, Object>> menuList = new ArrayList<>();
        Map<String, Object> menu = new HashMap<>();
        menu.put("id", menuInfo.get("menuNo"));
        menu.put("name", menuInfo.get("menuName"));
        menuList.add(menu);
        data.setData(menuList);
        return data;
    }

    @Override
    public ResultData saveMenu(MenuFormVo vo) {
        ResultData data = ResultData.success(null);
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(vo, sysMenu);
        vo.setMenuNo(vo.getpMenuNo());
//        SysMenu menu = sysMenuMapper.queryMenuById(vo);
        SysMenu menu = null;
        if (Objects.isNull(menu)) {
            data.setCode(400);
            data.setMessage("菜单添加失败,添加的父级菜单不存在");
            return data;
        }
        // 设置哪些参数信息
        sysMenu.setMenuNo(IdUtil.idByDate(new Date(), "yyyyMMddhhmmss", null));
        sysMenu.setGrade(menu.getGrade() + 1);
        sysMenu.setRanknum(Long.parseLong(IdUtil.idByDate(new Date(), "hhmmss", null)));
        sysMenuMapper.addMenu(sysMenu);
        data.setMessage("菜单添加成功");
        return data;
    }

    @Override
    public ResultData editMenu(MenuFormVo vo) {
        ResultData success = ResultData.success(null);
        SysMenu menu = new SysMenu();
        Map<String, Object> params = new HashMap<>();
        // todo 这里需要做一个将 对象信息复制到Map中的工具
        params.put("menuNo", vo.getMenuNo());
        Map<String, Object> menuInfo = sysMenuMapper.queryMenuById(params);
        if (Objects.isNull(menuInfo)) {
            success.setMessage("菜单编辑保存失败,当前编辑的菜单信息不存在");
            success.setCode(400);
            return success;
        }
        BeanUtils.copyProperties(vo, menu);
        int row = sysMenuMapper.updateMenu(menu);
        success.setMessage("编辑成功");
        return success;
    }

    @Override
    public Object deleteMenu(Map<String, Object> params) {
        ResultData success = ResultData.success(null);
        int row = sysMenuMapper.deleteMenu(params);
        return success;
    }

    @Override
    public Object deleteMenuList(Map<String, Object> params) {
        ResultData success = ResultData.success(null);
        MenuTreeVo treeVo = menuTreeList(params);
        List<MenuTreeVo> voList = delMenuList(treeVo);
        List<String> collect = voList.stream()
                .map(x -> x.getMenuNo())
                .collect(Collectors.toList());
        params.put("menuNos", collect);
        int row = sysMenuMapper.deleteMenuList(params);
        success.setMessage("删除成功");
        return success;
    }

    private List<MenuTreeVo> delMenuList(MenuTreeVo vo) {
        List<MenuTreeVo> voList = new ArrayList<>();
        if (Objects.isNull(vo.getTreeList()) || vo.getTreeList().size() == 0) {
            voList.add(vo);
        } else {
            List<MenuTreeVo> treeList = vo.getTreeList();
            for (MenuTreeVo tree : treeList) {
                voList.addAll(delMenuList(tree));
            }
            vo.setTreeList(null);
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 通过表单的菜单对象构建 数据库表对象信息
     *
     * @param menuForm
     * @return
     */
    private ResultData<SysMenu> createSysMenu(MenuFormVo menuForm) {
        Map<String, Object> params = new HashMap<>();
        params.put("menuNo", menuForm.getpMenuNo());
        ResultData<SysMenu> data = new ResultData<>();
        // 查询父菜单信息
        Map<String, Object> pMenu = sysMenuMapper.queryMenuById(params);
        if (Objects.isNull(pMenu)) {
            data.setCode(400);
            data.setMessage("添加失败,当前添加的菜单的父菜单不存在!");
            return data;
        }
        SysMenu sysMenu = new SysMenu();
        BeanUtils.copyProperties(menuForm, sysMenu);
        sysMenu.setMenuNo(IdUtil.idByDate(new Date(), "yyyyMMddhhmmss", null));
        sysMenu.setRanknum(Long.parseLong(IdUtil.idByDate(new Date(), "hhmmss", null)));
        sysMenu.setGrade((int) pMenu.get("grade") + 1);
        sysMenu.setValid((int) pMenu.get("valid"));
        int menuType = menuForm.getMenuType();
        if (menuType == 1) {    // 默认为系统顶级菜单,不设置菜单url
            sysMenu.setCode("");
        } else if (menuType == 2 || menuType == 3) {
            sysMenu.setCode(WebUtil.convertUrlToCode(sysMenu.getReqUrl()));
        }
        data.setData(sysMenu);
        data.setCode(200);
        return data;
    }

}
